﻿using System;
using System.Data.SqlTypes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Nvigorate.Common;

namespace Nvigorate.Test.Common
{
    [TestClass]
    public class TypeCasterTests
    {
        private enum Int16Enum : short
        {
            One,
            Two,
            Three
        }

        private enum Int32Enum // int by default
        {
            One,
            Two,
            Three
        }

        private enum Int64Enum : long
        {
            One,
            Two,
            Three
        }

        #region TestContext

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        #endregion

        #region Additional test attributes

        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //

        #endregion

        [TestMethod]
        public void Int16ToEnumTypeCast()
        {
            Assert.AreEqual(Int16Enum.One, TypeCaster.ConvertValue<Int16Enum>((short) Int16Enum.One));
        }

        [TestMethod]
        public void Int32ToEnumTypeCast()
        {
            Assert.AreEqual(Int32Enum.One, TypeCaster.ConvertValue<Int32Enum>((int) Int32Enum.One));
        }

        [TestMethod]
        public void Int64ToEnumTypeCast()
        {
            Assert.AreEqual(Int64Enum.One, TypeCaster.ConvertValue<Int64Enum>((long) Int64Enum.One));
        }

        [TestMethod]
        public void StringToEnumTypeCast()
        {
            Assert.AreEqual(Int32Enum.Three, TypeCaster.ConvertValue<Int32Enum>("Three"));
        }

        [TestMethod]
        public void NullableValueTypeCasts()
        {
            Assert.AreEqual(null, TypeCaster.ConvertValue<int?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<long?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<short?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<decimal?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<uint?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<byte?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<bool?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<DateTime?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<double?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<Single?>(DBNull.Value));
            Assert.AreEqual(null, TypeCaster.ConvertValue<string>(DBNull.Value));
        }

        [TestMethod]
        public void StringToDateTrimCast()
        {
            Assert.AreEqual(SqlDateTime.MinValue.Value,
                            TypeCaster.ConvertValue<DateTime>(" "));
        }
    }
}